Quadratic functions naturally arise when studying second order derivatives, and then by extension second order Taylor series approximations.
There is nothing complicated about a quadratic of a single input, but as we go up in dimension quadratics can become significantly more complex both in terms of the variety of shapes they can take as well as their general formalities.
Here we explain these complexities by discussing general quadratic functions, various ways of thinking about their construction, and the factors which control their shape.
Press the botton 'Toggle code' below to toggle code on and off for entire this presentation.
from IPython.display import display
from IPython.display import HTML
import IPython.core.display as di # Example: di.display_html('<h3>%s:</h3>' % str, raw=True)
# This line will hide code by default when the notebook is exported as HTML
di.display_html('<script>jQuery(function() {if (jQuery("body.notebook_app").length == 0) { jQuery(".input_area").toggle(); jQuery(".prompt").toggle();}});</script>', raw=True)
# This line will add a button to toggle visibility of code blocks, for use with the HTML export version
di.display_html('''<button onclick="jQuery('.input_area').toggle(); jQuery('.prompt').toggle();">Toggle code</button>''', raw=True)
The basic formula for a quadratic of a single input takes the familiar form
\begin{equation} g(w) = a + bw + cw^2 \end{equation}Below we plot two simple quadratics centered at the origin $g(w) = 6w^2$ and $g(w) = -w^2$
# create two quadratic functions
func1 = lambda w: 6*w**2
func2 = lambda w: -w**2
# use custom plotter to show both functions
title1 = '$g(w)=$3w^2$'; title2 = '$g(w)=$-w^2$';
linlib.plotters.double_2d_plot(func1 = func1, func2 = func2,title1 = title1,title2=title2,fontsize = 18,color = 'lime')
In three dimensions - where we have two inputs $w_1$ and $w_2$ - the same quadratic formula can be defined using one of the inputs. For example, using $w_1$ the formula takes the form
\begin{equation} g(w_1,w_2) = a + bw_1^{\,} + cw_1^2 \end{equation}In three dimensions this looks precisely like $g(w) = a + bw_1^{\,} + cw_1^2$ stretched along the $w_2$ input dimension - forming a half-pipe.
We plot the two and three dimensional versions of this quadratic side by side below.
# plot a single input quadratic in both two and three dimensions
func1 = lambda w: w**2
func2 = lambda w: w[0]**2
# use custom plotter to show both functions
title1 = '$g(w)=$w^2$'; title2 = '$g(w_1,w_2)=w_1^2$';
linlib.plotters.double_2d3d_plot(func1 = func1, func2 = func2,title1 = title1,title2=title2,fontsize = 18,color = 'lime')
as well as their sum (notice: this quadratic is convex along $w_1$ and concave along $w_2$)
\begin{equation} g(w_1,w_2) = w_1^2 - w_2^2 \end{equation}# plot a single input quadratic in both two and three dimensions
func1 = lambda w: w[0]**2
func2 = lambda w: -w[1]**2
# use custom plotter to show both functions
title1 = '$g_1(w_1,w_2)=w_1^2$'; title2 = '$g_2(w_1,w_2)=-w_2^2$'; title3 = '$g(w_1,w_2)=w_1^2-w_2^2$';
linlib.plotters.triple_3dsum_plot(func1 = func1, func2 = func2,title1 = title1,title2=title2,title3=title3,fontsize = 18,color = 'lime')
If instead we choose
$$ \begin{array} \ g_1(w_1,w_2) = w_1^2 \\ g_2(w_1,w_2) = w_2^2 \\ \end{array} $$and plot them along with their sum
\begin{equation} g(w_1,w_2) = w_1^2 + w_2^2 \end{equation}we see that the sum is convex along each coordinate axis, since each individual single input quadratic was convex.
# plot a single input quadratic in both two and three dimensions
func1 = lambda w: w[0]**2
func2 = lambda w: w[1]**2
# use custom plotter to show both functions
title1 = '$g_1(w_1,w_2)=w_1^2$'; title2 = '$g_2(w_1,w_2)=-w_2^2$'; title3 = '$g(w_1,w_2)=w_1^2+w_2^2$';
linlib.plotters.triple_3dsum_plot(func1 = func1, func2 = func2,title1 = title1,title2=title2,title3=title3,fontsize = 18,color = 'lime')
# animate a smooth transition between g = w_1^2 - w_2^2 and g = w_1^2 + w_2^2
# note: restart kernel if ggplot renderer has already been used (in any of the previous plots) before running - otherwise frames are very low resolutio
linlib.transform_animators.quadratic_3d_flexer.draw_it(num_slides = 100)
where $\mathbf{w} = \begin{bmatrix} w_1 \\ w_2 \end{bmatrix}$, $\mathbf{C} = \begin{bmatrix} c_{1} \,\,\,\, 0 \\ \,\,0 \,\,\,\, c_{2} \\ \end{bmatrix}$, $\mathbf{b} = \begin{bmatrix} b_1 \\ b_2 \end{bmatrix}$, and $a = a_1 + a_2$.
# rotate a quadratic
# note: restart kernel if ggplot renderer has already been used (in any of the previous plots) before running - otherwise frames are very low resolutio
func = lambda w: w[0]**2 - w[1]**2
linlib.transform_animators.quadratic_3d_rotater.draw_it(func = func,num_slides = 100,color = 'lime')